package com.yhao.stock.controller;

import com.yhao.stock.common.dto.StraightDeclineModel;
import com.yhao.stock.common.dto.UndulateModel;
import com.yhao.stock.common.utils.CSVUtil;
import com.yhao.stock.mapper.HisDataMapper;
import com.yhao.stock.mapper.StockInfoMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author : yhao
 * @Date : 2023/11/21 - 11:36
 * @Desc : TODO
 */
@RestController
@Slf4j
public class AnalysisController {

    static Integer continuous = 5;
    static Integer deviation = 20;

    @Autowired
    private HisDataMapper hisDataMapper;

    @Autowired
    private StockInfoMapper stockInfoMapper;

    @GetMapping("/getAllSDC/{startDate}/{endDate}")
    public String getAllSDC(@PathVariable String startDate, @PathVariable String endDate) {
        // List<StraightDeclineModel> resultList = new ArrayList<>();
        List<String> resultList = new ArrayList();
        List<String> codeList = stockInfoMapper.getCommonCode();
        StraightDeclineModel straightDeclineModel = null;
        String sdString = "";
        for (String code : codeList) {
            String name = stockInfoMapper.getNameByCode(code);
            List<BigDecimal> dataList = hisDataMapper.getPVData(code, startDate, endDate);
            List<Integer> sdList = getSDList(dataList);
            Integer maxCount = 0;
            if (sdList != null && sdList.size() > 0) {
                maxCount = Collections.max(sdList);
                straightDeclineModel = new StraightDeclineModel(code, name, maxCount + "");
                // resultList.add(straightDeclineModel);
                sdString = straightDeclineModel.toString();
                resultList.add(sdString);
            }
        }
        String filePath = "D:\\sdList.csv";
        CSVUtil.exportCsv(filePath, resultList);
        return "success";
    }

    /**
     * @param dCode
     * @param startDate
     * @param endDate
     * @return
     * @desc 获取超过三次下跌数量
     */
    @GetMapping("/getStraightDeclineCount/{dCode}/{startDate}/{endDate}")
    public StraightDeclineModel getStraightDeclineCount(@PathVariable String dCode, @PathVariable String startDate, @PathVariable String endDate) {
        String name = stockInfoMapper.getNameByCode(dCode);
        List<BigDecimal> dataList = hisDataMapper.getPVData(dCode, startDate, endDate);
        List<Integer> sdList = getSDList(dataList);
        Integer maxCount = Collections.max(sdList);
        return new StraightDeclineModel(dCode, name, maxCount + "");
    }

    /**
     * @param dataList
     * @return
     * @desc 计算数组连续下跌数量
     */
    public static List<Integer> getSDList(List<BigDecimal> dataList) {
        BigDecimal beforeValue = new BigDecimal(-1);
        List<Integer> resultList = new ArrayList<>();
        int count = 0;
        for (int i = 0; i < dataList.size(); i++) {
            BigDecimal currentValue = dataList.get(i);
            // 前值大于当前值
            if (beforeValue.compareTo(currentValue) > 0) {
                count++;
            } else {
                if (count >= 3) {
                    resultList.add(count);
                }
                count = 0;
            }
            beforeValue = currentValue;
        }
        return resultList;
    }

    /**
     * @param dCode
     * @param startDate
     * @param endDate
     * @return
     * @desc 获取波峰波谷
     */
    @GetMapping("/getPV/{dCode}/{startDate}/{endDate}")
    public List<UndulateModel> getPV(@PathVariable String dCode, @PathVariable String startDate, @PathVariable String endDate) {

        List<BigDecimal> pvData = hisDataMapper.getPVData(dCode, startDate, endDate);
        ArrayList<UndulateModel> undulateModels = new ArrayList<>();

        BigDecimal totalAvgPrice = totalAvgPrice(pvData); // 全部平均价格
        BigDecimal totalMaxPrice = Collections.max(pvData); // 全部的最大值
        BigDecimal totalMinPrice = Collections.min(pvData); // 全部的最小值
        BigDecimal middleDiffPrice = totalMaxPrice.subtract(totalAvgPrice).setScale(2, RoundingMode.HALF_UP);
        UndulateModel undulateModel = null;
        for (int i = continuous; i < pvData.size() - continuous; i++) {
            BigDecimal currPrice = pvData.get(i);
            List<BigDecimal> beforeFiveList = pvData.subList(i - continuous, i);
            List<BigDecimal> afterFiveList = pvData.subList(i + 1, i + continuous + 1);
            if (currPrice.compareTo(totalAvgPrice(beforeFiveList)) > 0 &&
                    currPrice.compareTo(totalAvgPrice(afterFiveList)) > 0 &&
                    currPrice.compareTo(Collections.max(beforeFiveList)) > 0 &&
                    currPrice.compareTo(Collections.max(afterFiveList)) > 0) {
                if (currPrice.compareTo(totalAvgPrice) > 0) {
                    if (totalMaxPrice.subtract(currPrice).divide(middleDiffPrice, 2, RoundingMode.HALF_UP).multiply(new BigDecimal(10)).compareTo(new BigDecimal(deviation)) < 0) {
                        undulateModel = new UndulateModel(i, currPrice, 1, false);
                        undulateModels.add(undulateModel);
                    }
                }
            }
            // }
            // 获取波谷
            // if (flag == 2 || flag == 1) {
            if (currPrice.compareTo(Collections.min(beforeFiveList)) < 0 &&
                    currPrice.compareTo(Collections.min(afterFiveList)) < 0 &&
                    currPrice.compareTo(totalAvgPrice(beforeFiveList)) < 0 &&
                    currPrice.compareTo(totalAvgPrice(afterFiveList)) < 0) {
                if (currPrice.compareTo(totalAvgPrice) < 0) {
                    if (currPrice.subtract(totalMinPrice).divide(middleDiffPrice, 2, RoundingMode.HALF_UP).multiply(new BigDecimal(10)).compareTo(new BigDecimal(deviation)) < 0) {
                        undulateModel = new UndulateModel(i, currPrice, 0, false);
                        undulateModels.add(undulateModel);
                    }
                }
            }
        }

        ArrayList<UndulateModel> finalList = new ArrayList();
        UndulateModel middleUndulateMode = null;
        for (int i = 0; i < undulateModels.size(); i++) {
            UndulateModel currUndulateModel = undulateModels.get(i);
            if (i == 0) {
                middleUndulateMode = currUndulateModel;
            } else {
                if (middleUndulateMode.getFlag() == currUndulateModel.getFlag()) {// 同类
                    if (middleUndulateMode.getFlag() == 1) {// 波峰
                        if (middleUndulateMode.getPrice().compareTo(currUndulateModel.getPrice()) < 0) {
                            middleUndulateMode = currUndulateModel;
                        }
                    } else {// 波谷
                        if (middleUndulateMode.getPrice().compareTo(currUndulateModel.getPrice()) > 0) {
                            middleUndulateMode = currUndulateModel;
                        }
                    }
                } else {
                    finalList.add(middleUndulateMode);
                    middleUndulateMode = currUndulateModel;
                }
            }
        }

        // for (int i = 0; i < finalList.size(); i++) {
        //     final UndulateModel undulateModel1 = finalList.get(i);
        //     if (undulateModel1.getFlag() == 0) {
        //         System.out.println("波谷：索引=[" + undulateModel1.getIndex() + "]  股价=[" + undulateModel1.getPrice() + "]");
        //     } else {
        //         System.out.println("波峰：索引=[" + undulateModel1.getIndex() + "]  股价=[" + undulateModel1.getPrice() + "]");
        //     }
        // }
        return finalList;
    }

    public static BigDecimal totalAvgPrice(List<BigDecimal> contents) {
        BigDecimal totalPrice = new BigDecimal(0);
        BigDecimal count = new BigDecimal(contents.size());
        for (BigDecimal content : contents) {
            totalPrice = totalPrice.add(content);
        }
        return totalPrice.divide(count, 2, RoundingMode.HALF_UP);
    }

}
